package models.weixin;

import jodd.bean.BeanCopy;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import models.constants.DeletedStatus;
import models.constants.Gender;
import models.enums.IdentityType;
import models.enums.UserFromType;
import models.merchant.Merchant;
import play.db.jpa.Model;
import play.modules.paginate.JPAExtPaginator;
import shopcart.ShopCart;
import utils.ObjectUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by shancheng on 16-6-17.
 */
@Entity
@Table(name = "power_web_users")
public class WebUser extends Model {

    private static final long serialVersionUID = 289109934185631L;
    public static final String WXMP_CACHEKEY  = "WxMpUser2_";

    /**
     * 微信用户名，fromUserName.
     * TODO: 加上索引.
     */
    @Column(name = "openId", length = 50)
    public String openId;

    /**
     * 所属店面
     */
    @JoinColumn(name="merchant_id")
    @ManyToOne
    public Merchant merchant;

    /**
     * 用户属于哪一个微信号
     */
    @JoinColumn(name = "weixin_data")
    @ManyToOne
    public WeixinData weixinData;


    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "from_type")
    public UserFromType fromType = UserFromType.WEIXIN;


    /**
     * 用户身份  普通用户  商户
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "identity_type")
    public IdentityType identityType = IdentityType.USER;


    /**
     * 认证授权码 本人/本商户 授权码 具有唯一性
     */
    @Column(name = "identity_code")
    public String identityCode;

    /**
     * 介绍人授权码  跟 identityCode 对应
     */
    @Column(name = "introduce_code")
    public String introduceCode;

    /**
     * 微信确认身份用
     */
    @Column(name = "uuid")
    public String uuid;


    /**
     * 是否订阅.
     * 用户是否订阅该公众号标识，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
     * 可考虑通过一个定时任务查询当前公众号的用户订阅状态.
     */
    @Column(name = "subcribed")
    public Boolean subcribed;

    /**
     * 用户的昵称
     */
    @Column(name = "nick_name", length = 50)
    public String nickName;


    @Enumerated(EnumType.STRING)
    @Column(name = "sex", length = 10)
    public Gender sex;

    /**
     * 用户语言
     */
    @Column(name = "user_lang", length = 20)
    public String language;


    @Column(name = "city", length = 20)
    public String city;


    /**
     * 领取卡券次数
     */
    @Column(name = "give_coupon_count")
    public Integer giveCouponCount = 0;


    @Column(name = "country", length = 20)
    public String country;


    /**
     * 是否第一次进入
     */
    @Column(name = "is_first")
    public Boolean isFirst;

    /**
     * 用户头像路径.
     * <p/>
     * 保存微信文件到本地.
     */
    @Column(name = "head_img_url", length = 200)
    public String headImgUrl;

    @Column(name = "phone")
    public String phone;

    @Column(name = "birthDay")
    public String birthDay;

    @Column(name = "sign")
    public String sign;

    /**
     * 用户注册时间.
     * 用户注册时间
     */
    @Column(name = "created_at")
    public Date createAt;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "deleted")
    public DeletedStatus deleted = DeletedStatus.UN_DELETED;

    /**
     * 备注
     */
    @Column (name = "remark")
    public String remark;

    /**
     * 支付宝号
     */
    @Column(name = "alipay_id")
    public String alipayId;

    /**
     * 分页查询.
     */
    public static JPAExtPaginator<WebUser> findByCondition(Map<String, Object> conditionMap, String orderByExpress, int pageNumber, int pageSize) {
        StringBuilder xsqlBuilder = new StringBuilder("t.deleted=models.constants.DeletedStatus.UN_DELETED ")
                .append("/~ and t.phone = {phone} ~/")
                .append("/~ and t.merchant.id = {merchantId} ~/")
                .append("/~ and t.nickName like {nickName} ~/");

        util.xsql.XsqlBuilder.XsqlFilterResult result = new util.xsql.XsqlBuilder().generateHql(xsqlBuilder.toString(), conditionMap);
        JPAExtPaginator<WebUser> orderPage = new JPAExtPaginator<WebUser>("WebUser t", "t", WebUser.class,
                result.getXsql(), conditionMap).orderBy(orderByExpress);
        orderPage.setPageNumber(pageNumber);
        orderPage.setPageSize(pageSize);
        orderPage.setBoundaryControlsEnabled(false);
        return orderPage;
    }

    /**
     * 按weixinUser值更新指定ID的WeixinUser.
     */
    public static void update(Long id, WebUser weixinUser) {
        WebUser oldWeixinUser = WebUser.findById(id);
        BeanCopy.beans(weixinUser, oldWeixinUser).ignoreNulls(true).copy();
        oldWeixinUser.save();
    }

    /**
     * 删除指定ID的WeixinMenu
     */
    public static void delete(Long id) {
        WebUser weixinUser = WebUser.findById(id);
        weixinUser.deleted = DeletedStatus.DELETED;
        weixinUser.save();
    }

    /**
     * 根据OpenId查询用户
     */
    public static WebUser findByOpenId(String openId) {
        return WebUser.find("openId = ? and deleted = ?" , openId , DeletedStatus.UN_DELETED).first();
    }

    /**
     * 查询出商户指定OpenId的用户.
     */
    public static WebUser findOrCreateMerchantWxUser(Merchant merchant, WxMpUser wxMpUser , String dcode) {
        WebUser webUser = WebUser.find("weixinData = ? and openId=? and deleted = ?", merchant.weixinData , wxMpUser.getOpenId() , DeletedStatus.UN_DELETED).first();
        if (webUser == null) {
            webUser = new WebUser();
            webUser.createAt = new Date();
            webUser.deleted = DeletedStatus.UN_DELETED;
            webUser.weixinData = merchant.weixinData;
            webUser.merchant = merchant;
            webUser.openId = wxMpUser.getOpenId();
            webUser.nickName = wxMpUser.getNickname();
            webUser.subcribed = Boolean.FALSE;
            webUser.introduceCode = dcode;
            webUser.city = wxMpUser.getCity();
            webUser.country = wxMpUser.getCountry();
            webUser.language = wxMpUser.getLanguage();
            webUser.headImgUrl = wxMpUser.getHeadImgUrl();
            webUser.isFirst = true;
            if ("1".equals(wxMpUser.getSex()) || "男".equals(wxMpUser.getSex())) {
                webUser.sex = Gender.MALE;
            } else if ("2".equals(wxMpUser.getSex()) || "女".equals(wxMpUser.getSex())) {
                webUser.sex = Gender.FEMALE;
            } else {
                webUser.sex = Gender.UNKNOWN;
            }
            webUser.subcribed = wxMpUser.isSubscribe();
            webUser.save();
        }
        webUser.identityCode = ObjectUtil.coverNumber(webUser.id.intValue() , 6);
        webUser.save();
        return webUser;
    }

    public static List<WebUser> findAvailable() {
        return WebUser.find("deleted = ?" , DeletedStatus.UN_DELETED).fetch();
    }


    /**
     * 根据授权码查询用户
     * @param identityCode
     * @return
     */
    public static WebUser findByIdentityCode(String identityCode) {
        return WebUser.find("identityCode = ? and deleted = ?" , identityCode , DeletedStatus.UN_DELETED).first();
    }

    public static WebUser findByUserId(long id){
        return WebUser.find(" id = ? and deleted = ?",id,DeletedStatus.UN_DELETED).first();
    }



    public static WebUser findByUUid(String uuid) {
        return WebUser.find("uuid = ? and deleted = ?" , uuid , DeletedStatus.UN_DELETED).first();
    }
    public  static   List<WebUser> findBYWeiXinDataId(Long merchantId){
        Merchant merchant = Merchant.findByMerchantId(merchantId);
        return  WebUser.find("deleted = ? and weixinData.id = ?",DeletedStatus.UN_DELETED, merchant.weixinData.id).fetch();
    }


    public static WebUser findByPhone(String phone) {
        return WebUser.find("phone = ? and deleted = ?" , phone , DeletedStatus.UN_DELETED).first();
    }

    public static List<WebUser> loadByMerchant(long merchantId){
        return WebUser.find(" deleted = ? and merchant.id = ? " , DeletedStatus.UN_DELETED , merchantId).fetch();
    }

    public static List<WebUser> findUserByPhone(String phone) {
        return WebUser.find("phone = ? and deleted = ?" , phone , DeletedStatus.UN_DELETED).fetch();
    }

    /**
     * 手机号是否被占用
     * @param phone
     * @return
     */
    public static WebUser findByPhoneOccupy(String phone,long webUserId) {
        return WebUser.find("phone = ? and deleted = ?  and id != ? " , phone , DeletedStatus.UN_DELETED,webUserId).first();
    }
}
